package com.example.demo.service.Impl;

import com.example.demo.mapper.UserMapper;
import com.example.demo.pojo.Room;
import com.example.demo.pojo.User;
import com.example.demo.service.GameService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * @author luolinila
 */
@Service
public class GameServiceImpl implements GameService {

    @Resource
    private RedisTemplate redisTemplate;
    @Autowired
    private UserMapper userMapper;

    //创建房间
    @Override
    public int createGame() {
        //获取不重复房间ID
        int id = 100000 + (new Random()).nextInt(900000);
        while (redisTemplate.opsForValue().get("room_" + id) != null) {
            id = 100000 + (new Random()).nextInt(900000);
        }
        Room room = new Room(id);
        //更新redis中房间状态
        updateRoomState(room);
        return id;
    }

    //获取房间
    @Override
    public Room getRoom(int id) {
        return (Room) redisTemplate.opsForValue().get("room_" + id);
    }

    //向房间添加用户
    @Override
    public Room addUser(Room room, User user) {
        int sign = room.addUser(user);
        if (sign == -1) {
            return null;
        }
        //更新redis中房间状态
        updateRoomState(room);
        return room;
    }

    //移除房间内用户
    @Override
    public Room removeUser(Room room, User user) {
        int manCount = room.removeUser(user);
        if (manCount == -1) {
            return null;
        }
        if (manCount == 0) {
            //房间中没有玩家时 删除redis中房间
            redisTemplate.delete("room_" + room.getRoomId());
        }else {
            //更新redis中房间状态
            updateRoomState(room);
        }
        return room;
    }

    //开始对局
    @Override
    public Room startGame(Room room) {
        if (room.getState() == 1) {
            return null;
        }
        if(room.getUsers().size() < 2) {
            return null;
        }
        int n = room.start();
        if(n < 0) {
            return null;
        }
        updateRoomState(room);
        return room;
    }

    //更新对局数据
    @Override
    public void update(Room room) {
        HashSet<User> users = new HashSet<>();
        //从 mysql 中获取数据
        for(User u: room.getUsers()) {
            users.add(userMapper.selectByUid(u.getUid()));
        }
        //更新内存中房间状态
        room.setUsers(users);
    }

    //强制结束对局
    @Override
    public Room stop(Room room) {
        //对局已经为结束状态
        if(room.getState() == 0) {
            return null;
        }
        room.stop();
        //更新MySql状态
        //从 users.balance 中更新至 mysql
        //user -> mysql
        for (User user: room.getUsers()) {
            userMapper.updateUserBalance(user.getUid(), user.getBalance());
        }
        //更新内存中房间状态
        //mysql -> 内存
        update(room);
        //更新redis状态
        updateRoomState(room);
        return room;
    }

    //结束对局
    @Override
    public Room endGame(Room room) {
        //对局已经为结束状态
        if (room.getState() == 0) {
            return null;
        }
        room.end();
        //更新MySql状态
        //从 users.balance 中更新至 mysql
        //内存 -> mysql
        for(User user: room.getUsers()) {
            userMapper.updateUserBalance(user.getUid(), user.getBalance());
        }
        //更新内存中房间状态
        //mysql -> 内存
        update(room);
        //更新redis状态
        updateRoomState(room);
        return room;
    }

    //更新redis中房间状态
    @Override
    public void updateRoomState(Room room) {
        redisTemplate.opsForValue().set("room_" + room.getRoomId(), room, 1, TimeUnit.DAYS);
    }

    //玩家操作
    @Override
    public Room action(Room room, User user, String action) {
        //通过 id 校验是否为行动玩家
        if (user.getUid() != room.getActionUserId()) {
            //操作玩家错误
            return null;
        }
        int res = 0;
        // 0:操作成功   -1:操作失败
        //action:
        //跟注 call
        if (action.contains("call")) {
            res = room.call();
        }
        //加注 raise
        if (action.contains("raise")) {
            res = room.raise(action);
        }
        //All in
        if (action.contains("allIn")) {
            res = room.allIn();
        }
        //弃牌 fold
        if (action.contains("fold")) {
            res = room.fold();
        }
        System.out.println(res);
        if(res == 1) {
            endGame(room);
        }
        //更新redis状态
        updateRoomState(room);
        return res < 0 ? null : room;
    }
}
